<template>
  <a-layout class="layout">
    <a-layout-header class="header">
      <a-space>
        <a-select
          placeholder="neuron"
          style="width: 180px"
          v-model:value="queryField.neuron"
          :options="neuronItems"
          @change="neuronChange"
          allow-clear
        />
        <a-select
          placeholder="node"
          style="width: 180px"
          v-model:value="queryField.node"
          :options="nodeItems"
          @change="nodeChange"
          allow-clear
        />
        <a-select
          placeholder="group"
          v-model:value="queryField.group"
          :options="groupItems"
          style="width: 180px"
          allow-clear
        />
        <a-button type="primary" :loading="loading" @click="query">
          <template #icon><SearchOutlined /></template>查询</a-button
        >
        <a-button @click="showModel('add')">
          <template #icon><plus-outlined /></template>添加</a-button
        >
        <a-button
          type="primary"
          @click="loginNeurons"
          danger
          :loading="loginLoading"
          ><template #icon><api-outlined /></template>重新连接</a-button
        >
      </a-space>
    </a-layout-header>
    <a-layout-content class="content">
      <a-table
        class="ant-table-striped"
        :columns="columns"
        :row-key="(record) => record.ts"
        :data-source="dataSource"
        :loading="loading"
        :row-class-name="
          (_, index) => (index % 2 === 1 ? 'table-striped' : null)
        "
        :pagination="{
          total: total,
          onChange: pageChange,
          defaultPageSize: 5,
        }"
        bordered
      >
        <template #bodyCell="{ column, text, record }">
          <template v-if="column.dataIndex === 'neuron'">
            <a :href="record.nhost" target="_blank">{{ text }}</a>
          </template>
          <template v-if="column.dataIndex === 'operate'">
            <a-button
              size="small"
              type="link"
              @click="showModel('edit', record)"
              ><template #icon><edit-outlined /></template>编辑</a-button
            >
            <a-divider type="vertical" />
            <a-button
              size="small"
              type="link"
              danger
              @click="deleteTagById(record.ts)"
              ><template #icon><delete-outlined /></template>删除</a-button
            >
          </template>
        </template>
      </a-table>
      <a-modal
        width="20%"
        v-model:visible="visible"
        :title="title"
        :confirm-loading="confirmLoading"
        okText="保存"
        cancelText="取消"
        @ok="submit"
      >
        <template v-if="isEdit">
          <a-row :gutter="16" style="margin-top: 8px">
            <a-col :span="6" style="text-align: left">ID</a-col>
            <a-col :span="18"
              ><a-input :value="editTagVal.ts" size="small" disabled
            /></a-col>
          </a-row>
        </template>
        <a-row :gutter="16" style="margin-top: 8px">
          <a-col :span="6" style="text-align: left">接收编码</a-col>
          <a-col :span="18"
            ><a-input
              v-model:value="editTagVal.receivename"
              size="small"
              allow-clear
          /></a-col>
        </a-row>
        <a-row :gutter="16" style="margin-top: 8px">
          <a-col :span="6" style="text-align: left">Neuron</a-col>
          <a-col :span="18">
            <a-select
              size="small"
              style="width: 100%"
              v-model:value="editTagVal.nhost"
              :options="neuronItems"
              @change="editNeuronChange"
              allow-clear
            ></a-select
          ></a-col>
        </a-row>
        <a-row :gutter="16" style="margin-top: 8px">
          <a-col :span="6" style="text-align: left">Node</a-col>
          <a-col :span="18"
            ><a-select
              size="small"
              style="width: 100%"
              v-model:value="editTagVal.node"
              :options="editNodeItems"
              @change="editNodeChange"
              allow-clear
            ></a-select
          ></a-col>
        </a-row>
        <a-row :gutter="16" style="margin-top: 8px">
          <a-col :span="6" style="text-align: left">Group</a-col>
          <a-col :span="18"
            ><a-select
              size="small"
              style="width: 100%"
              v-model:value="editTagVal.groupname"
              :options="editGroupItems"
              @change="editGroupChange"
              allow-clear
            ></a-select
          ></a-col>
        </a-row>
        <a-row :gutter="16" style="margin-top: 8px">
          <a-col :span="6" style="text-align: left">点位名称</a-col>
          <a-col :span="18"
            ><a-select
              size="small"
              style="width: 100%"
              v-model:value="editTagVal.tagname"
              :options="editTagItems"
              allow-clear
            ></a-select
          ></a-col>
        </a-row>
      </a-modal>
    </a-layout-content>
  </a-layout>
</template>

<script setup>
import { onMounted, ref } from "vue";
import {
  getPagedTags,
  editTag,
  getNeurons,
  deleteTag,
} from "../../utils/tdengineApi";
import { login, getNodes, getGroups, getTags } from "../../utils/neuronApi";
import { message } from "ant-design-vue";
import {
  SearchOutlined,
  EditOutlined,
  DeleteOutlined,
  ApiOutlined,
  ClearOutlined,
  PlusOutlined,
} from "@ant-design/icons-vue";

const loading = ref(false); // 查询和表格加载
const confirmLoading = ref(false); // 编辑界面提交加载
const loginLoading = ref(false); // 重新登录加载
const dataSource = ref([]); // 数据源
const visible = ref(false); // 控制编辑界面显示
const title = ref(""); // 编辑界面标题
const editTagVal = ref({}); // 编辑界面修改记录
const neuronItems = ref([]); // neuron下拉框选项，查询和编辑界面
const nodeItems = ref([]); // node下拉框选项，查询界面
const groupItems = ref([]); // group下拉框选项，查询界面
const editNodeItems = ref([]); // node下拉框选项，编辑界面
const editGroupItems = ref([]); // group下拉框选项，编辑界面
const editTagItems = ref([]); // tag下拉框选项，编辑界面
const queryField = ref({}); // 查询标签
let flag = true; // 是否是首次打开页面
const total = ref(0);
const current = ref(1);
const isEdit = ref(false);

const columns = [
  {
    title: "ID",
    dataIndex: "ts",
    sorter: (a, b) => new Date(a.ts) - new Date(b.ts),
    width: "16%",
    align: "center",
  },
  {
    title: "接收编码",
    dataIndex: "receivename",
    width: "12%",
    align: "center",
  },
  {
    title: "点位名称",
    dataIndex: "tagname",
    width: "16%",
    align: "center",
  },
  {
    title: "Neuron",
    dataIndex: "neuron",
    width: "16%",
    align: "center",
  },
  {
    title: "Node",
    dataIndex: "node",
    width: "12%",
    align: "center",
  },
  {
    title: "Group",
    dataIndex: "groupname",
    width: "12%",
    align: "center",
  },
  {
    title: "操作",
    dataIndex: "operate",
    width: "16%",
    align: "center",
  },
];

onMounted(async () => {
  await query();
  await loginNeurons();
  await getneuronItems();
});

// 查询tdengine中的数据
const query = async (skipCount, resultCount) => {
  if (!skipCount || !resultCount) {
    skipCount = 1;
    resultCount = 5;
  }
  loading.value = true;
  let data = await getPagedTags(
    queryField.value,
    (skipCount - 1) * resultCount,
    resultCount
  );
  dataSource.value = data.data;
  total.value = data.total;

  setTimeout(() => {
    loading.value = false;
  }, 200);
};

// 登录neuron
const loginNeurons = async () => {
  loginLoading.value = true;
  let hosts = [];
  dataSource.value.forEach((e) => {
    let index = hosts.indexOf(e.nhost);
    if (index === -1) {
      hosts.push(e.nhost);
    }
  });
  await login(hosts);
  if (!flag) {
    setTimeout(() => {
      loginLoading.value = false;
      message.success("重连成功");
    }, 2000);
  } else {
    loginLoading.value = false;
    flag = false;
  }
};

// 获取所有neuron
const getneuronItems = async () => {
  let data = await getNeurons(undefined, 0, 0);
  data.data.forEach((v) => {
    neuronItems.value.push({
      label: v.neuron,
      value: v.nhost,
    });
  });
};

// 根据neuron获取node
const getNodeItems = async (neuron, mode) => {
  if (neuron) {
    let data = await getNodes(neuron);
    if (mode == "query") {
      nodeItems.value = data;
    } else {
      editNodeItems.value = data;
    }
  }
};

// 根据neuron和node获取group
const getGroupItems = async (neuron, node, mode) => {
  if (neuron && node) {
    let data = await getGroups(neuron, node);
    if (mode == "query") {
      groupItems.value = data;
    } else {
      editGroupItems.value = data;
    }
  }
};

// 根据neuron，node和group获取所有点位
const getTagItems = async (neuron, node, group) => {
  if (neuron && node && group) {
    let data = await getTags(neuron, node, group);
    editTagItems.value = data;
  }
};

const deleteTagById = async (id) => {
  await deleteTag(id);
  await query();
};

// 查询neuron下拉框发生改变时
const neuronChange = async () => {
  if (queryField.value.neuron) {
    await getNodeItems(queryField.value.neuron, "query");
  } else {
    nodeItems.value = [];
  }
  await nodeChange();
  queryField.value.node = undefined;
};

// 查询node下拉框发生改变时
const nodeChange = async () => {
  if (queryField.value.neuron && queryField.value.node) {
    await getGroupItems(
      queryField.value.neuron,
      queryField.value.node,
      "query"
    );
  } else {
    groupItems.value = [];
  }
  queryField.value.group = undefined;
};

// 打开编辑框
const showModel = async (flag, record) => {
  visible.value = true;
  editTagVal.value = {};
  confirmLoading.value = false;
  if (flag === "edit") {
    title.value = "编辑";
    isEdit.value = true;
    await getNodeItems(record.nhost, "edit");
    await getGroupItems(record.nhost, record.node, "edit");
    await getTagItems(record.nhost, record.node, record.groupname);
    editTagVal.value = {
      ts: record.ts,
      receivename: record.receivename,
      neuron: record.neuron,
      nhost: record.nhost,
      node: record.node,
      groupname: record.groupname,
      tagname: record.tagname,
    };
  } else if (flag === "add") {
    title.value = "添加";
    editTagVal.value.ts = getTimestamp();
    isEdit.value = false;
  }
};

// 编辑neuron下拉框发生改变时
const editNeuronChange = async () => {
  if (editTagVal.value.nhost) {
    await getNodeItems(editTagVal.value.nhost, "edit");
    await editNodeChange();
  } else {
    editNodeItems.value = [];
  }
  editTagVal.value.node = undefined;
};

// 编辑node下拉框发生改变时
const editNodeChange = async () => {
  if (editTagVal.value.nhost && editTagVal.value.node) {
    await getGroupItems(editTagVal.value.nhost, editTagVal.value.node, "edit");
    await editGroupChange();
  } else {
    editGroupItems.value = [];
  }
  editTagVal.value.groupname = undefined;
};

// 编辑group下拉框发生改变时
const editGroupChange = async () => {
  if (
    editTagVal.value.nhost &&
    editTagVal.value.node &&
    editTagVal.value.groupname
  ) {
    await getTagItems(
      editTagVal.value.nhost,
      editTagVal.value.node,
      editTagVal.value.groupname
    );
  } else {
    editTagItems.value = [];
  }
  editTagVal.value.tagname = undefined;
};

// 提交
const submit = async () => {
  if (
    editTagVal.value.receivename != undefined &&
    editTagVal.value.receivename != "" &&
    editTagVal.value.nhost != undefined &&
    editTagVal.value.nhost != "" &&
    editTagVal.value.node != undefined &&
    editTagVal.value.node != "" &&
    editTagVal.value.groupname != undefined &&
    editTagVal.value.groupname != "" &&
    editTagVal.value.tagname != undefined &&
    editTagVal.value.tagname != ""
  ) {
    confirmLoading.value = true;
    editTagVal.value.neuron = neuronItems.value.filter(
      (v) => v.value == editTagVal.value.nhost
    )[0].label;
    await editTag(editTagVal.value);

    confirmLoading.value = false;
    visible.value = false;
    await query();
  } else {
    message.warn("参数输入不正确");
  }
};

const pageChange = async (page, pageSize) => {
  await query(page, pageSize);
};

// 获取时间戳
const getTimestamp = () => {
  return new Date().getTime().toString();
};
</script>

<style scoped>
.header {
  background: #fff;
  height: 80px;
}

.content {
  height: 100%;
}

.ant-table-striped :deep(.table-striped) td {
  background-color: #d8e3e7;
}
</style>
